package com.avic.modules.equipment.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.avic.common.service.impl.BaseServiceImpl;
import com.avic.common.utils.QueryHelpPlus;
import com.avic.dozer.service.IGenerator;
import com.avic.exception.BadRequestException;
import com.avic.modules.equipment.domain.Equipment;
import com.avic.modules.equipment.domain.EquipmentMaintain;
import com.avic.modules.equipment.domain.vo.Accept;
import com.avic.modules.equipment.domain.vo.MaintainVo;
import com.avic.modules.equipment.service.EquipmentMaintainService;
import com.avic.modules.equipment.service.dto.EquipmentMaintainDto;
import com.avic.modules.equipment.service.dto.EquipmentMaintainQueryCriteria;
import com.avic.modules.equipment.service.mapper.EquipmentMaintainMapper;
import com.avic.modules.equipment.service.mapper.EquipmentMapper;
import com.avic.modules.log.domain.vo.LogEnumeration;
import com.avic.modules.log.domain.vo.LogVo;
import com.avic.modules.log.service.LogsService;
import com.avic.modules.log.utils.ContrastObjUtil;
import com.avic.modules.system.domain.User;
import com.avic.modules.system.service.mapper.SysUserMapper;
import com.avic.utils.FileUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageInfo;
import lombok.AllArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.*;

/**
 * @author zhangzikang 设备维护表
 * @date 2022-08-14
 */
@Service(value = "equipmentMaintainService")
@AllArgsConstructor
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class EquipmentMaintainServiceImpl extends BaseServiceImpl
        <EquipmentMaintainMapper, EquipmentMaintain> implements EquipmentMaintainService {

    private final IGenerator generator;
    private final EquipmentMaintainMapper maintainMapper;
    private final EquipmentMapper equipmentMapper;
    private final SysUserMapper userMapper;
    private final LogsService logsService;

    @Override
    public Map<String, Object> queryAll(EquipmentMaintainQueryCriteria criteria, Pageable pageable) {
        try {
            if(criteria.getEquipNumber()!=null){
                QueryWrapper<Equipment> wrapper = new QueryWrapper<>();
                wrapper.eq("id", criteria.getEquipNumber());
                Equipment equipment = equipmentMapper.selectOne(wrapper);
                Set<String> all = new HashSet<>();
                if(equipment!=null){
                    QueryWrapper<Equipment> wrapper2 = new QueryWrapper<>();
                    wrapper2.eq("equip_son", equipment.getId());
                    List<Equipment> equipment2 = equipmentMapper.selectList(wrapper2);
                    for(Equipment equip:equipment2){
                        all.add(equip.getId());
                    }
                    all.add(equipment.getId());
                }
                criteria.setEquipNumber1(all);
            }
            if(criteria.getStation()!=null){
                QueryWrapper<Equipment> wrapper = new QueryWrapper<>();
                wrapper.eq("stack_number", criteria.getStation());
                List<Equipment> equipment = equipmentMapper.selectList(wrapper);
                Set<String> all = new HashSet<>();
                for(Equipment equip:equipment){
                    all.add(equip.getId());
                }
                criteria.setEquipNumber1(all);
            }

            if(criteria.getAggregate()!=null && criteria.getAggregate()!=""){
                List<Accept> parse = JSONArray.parseArray(criteria.getAggregate(),Accept.class);
                // 包含id
                Set<String> idAll = new HashSet<>();
                QueryWrapper<EquipmentMaintain> wrapper = new QueryWrapper<>();
                for(Accept accept:parse){
                    if(accept.getName().equals("workOrder")){
                        if(accept.getCondition().equals("1")){
                            wrapper.notLike("work_order",accept.getValue());
                        }else if(accept.getCondition().equals("0")){
                            wrapper.like("work_order",accept.getValue());
                        }
                    }else if(accept.getName().equals("equipName")){
                        if(accept.getCondition().equals("1")){
                            wrapper.notLike("equip_name",accept.getValue());
                        }else if(accept.getCondition().equals("0")){
                            wrapper.like("equip_name",accept.getValue());
                        }
                    }else if(accept.getName().equals("frequency")){
                        if(accept.getCondition().equals("1")){
                            wrapper.notLike("frequency",accept.getValue());
                        }else if(accept.getCondition().equals("0")){
                            wrapper.like("frequency",accept.getValue());
                        }
                    }else if(accept.getName().equals("grade")){
                        if(accept.getCondition().equals("1")){
                            wrapper.notLike("grade",accept.getValue());
                        }else if(accept.getCondition().equals("0")){
                            wrapper.like("grade",accept.getValue());
                        }
                    }else if(accept.getName().equals("maintainerName")) {
                        if (accept.getCondition().equals("1")) {
                            wrapper.notLike("maintainer_name", accept.getValue());
                        } else if (accept.getCondition().equals("0")) {
                            wrapper.like("maintainer_name", accept.getValue());
                        }
                    }else if(accept.getName().equals("photographTime")){
                        if (accept.getCondition().equals("2")){
                            String value = accept.getValue();
                            String[] split = value.split(",", 0);
                            String start = null;
                            String end = null;
                            int sum = 0;
                            for(String spl:split){
                                if(sum==1){
                                    end = spl;
                                } else {
                                    start = spl;
                                }
                                sum ++;
                            }
                            wrapper.between("photograph_time", start, end);
                        } else if(accept.getCondition().equals("1")) {
                            wrapper.notBetween("photograph_time",accept.getValue()+" 00:00:00",accept.getValue()+" 23:59:59").or().isNull("photograph_time");
                        } else if(accept.getCondition().equals("0")) {
                            wrapper.between("photograph_time",accept.getValue()+" 00:00:00",accept.getValue()+" 23:59:59");
                        }
                    }
                }
                List<EquipmentMaintain> equipmentMaintains = maintainMapper.selectList(wrapper);
                for(EquipmentMaintain equip:equipmentMaintains){
                    idAll.add(equip.getId());
                }
                if(equipmentMaintains.size()==0){
                    idAll.add("没有东西");
                }
                criteria.setIdAll(idAll);
            }
        } catch (JSONException e) {
            throw new BadRequestException("参数格式不匹配");
        }
        String order = "work_order desc";
        getPageSort(pageable,order);
        PageInfo<EquipmentMaintain> page = new PageInfo<>(queryAll(criteria));
        List<EquipmentMaintainDto> convert = generator.convert(page.getList(), EquipmentMaintainDto.class);
        for(EquipmentMaintainDto equip:convert){
            if(equip.getPhotograph()!=null && !equip.getPhotograph().equals("")){
                String[] split = equip.getPhotograph().split(",");
                equip.setEquipSum(split.length);
            }else {
                equip.setEquipSum(0);
            }
            Equipment equipment = equipmentMapper.selectById(equip.getEquipNumber());
            if(equipment!=null){
                equip.setEquipCategoryId(equipment.getEquipCategoryId());
                equip.setStackNumber(equipment.getStackNumber());
            }
        }
        Map<String, Object> map = new LinkedHashMap<>(2);
        map.put("content",convert);
        map.put("totalElements", page.getTotal());
        return map;
    }

    @Override
    public List<EquipmentMaintain> queryAll(EquipmentMaintainQueryCriteria criteria) {
        return baseMapper.selectList(QueryHelpPlus.getPredicate(EquipmentMaintain.class,criteria));
    }

    @Override
    public List<EquipmentMaintain> queryAlls(EquipmentMaintainQueryCriteria criteria, Pageable pageable) {
        if(criteria.getEquipNumber()!=null){
            QueryWrapper<Equipment> wrapper = new QueryWrapper<>();
            wrapper.eq("id", criteria.getEquipNumber());
            Equipment equipment = equipmentMapper.selectOne(wrapper);
            Set<String> all = new HashSet<>();
            if(equipment!=null){
                QueryWrapper<Equipment> wrapper2 = new QueryWrapper<>();
                wrapper2.eq("equip_son", equipment.getId());
                List<Equipment> equipment2 = equipmentMapper.selectList(wrapper2);
                for(Equipment equip:equipment2){
                    all.add(equip.getId());
                }
                all.add(equipment.getId());
            }
            criteria.setEquipNumber1(all);
        }
        if(criteria.getStation()!=null){
            QueryWrapper<Equipment> wrapper = new QueryWrapper<>();
            wrapper.eq("stack_number", criteria.getStation());
            List<Equipment> equipment = equipmentMapper.selectList(wrapper);
            Set<String> all = new HashSet<>();
            for(Equipment equip:equipment){
                all.add(equip.getId());
            }
            criteria.setEquipNumber1(all);
        }

        if(criteria.getAggregate()!=null && criteria.getAggregate()!=""){
            List<Accept> parse = JSONArray.parseArray(criteria.getAggregate(),Accept.class);
            // 包含id
            Set<String> idAll = new HashSet<>();
            QueryWrapper<EquipmentMaintain> wrapper = new QueryWrapper<>();
            for(Accept accept:parse){
                if(accept.getName().equals("workOrder")){
                    if(accept.getCondition().equals("1")){
                        wrapper.notLike("work_order",accept.getValue());
                    }else if(accept.getCondition().equals("0")){
                        wrapper.like("work_order",accept.getValue());
                    }
                }else if(accept.getName().equals("equipName")){
                    if(accept.getCondition().equals("1")){
                        wrapper.notLike("equip_name",accept.getValue());
                    }else if(accept.getCondition().equals("0")){
                        wrapper.like("equip_name",accept.getValue());
                    }
                }else if(accept.getName().equals("frequency")){
                    if(accept.getCondition().equals("1")){
                        wrapper.notLike("frequency",accept.getValue());
                    }else if(accept.getCondition().equals("0")){
                        wrapper.like("frequency",accept.getValue());
                    }
                }else if(accept.getName().equals("grade")){
                    if(accept.getCondition().equals("1")){
                        wrapper.notLike("grade",accept.getValue());
                    }else if(accept.getCondition().equals("0")){
                        wrapper.like("grade",accept.getValue());
                    }
                }else if(accept.getName().equals("maintainerName")) {
                    if (accept.getCondition().equals("1")) {
                        wrapper.notLike("maintainer_name", accept.getValue());
                    } else if (accept.getCondition().equals("0")) {
                        wrapper.like("maintainer_name", accept.getValue());
                    }
                }else if(accept.getName().equals("photographTime")){
                    if (accept.getCondition().equals("2")){
                        String value = accept.getValue();
                        String[] split = value.split(",", 0);
                        String start = null;
                        String end = null;
                        int sum = 0;
                        for(String spl:split){
                            if(sum==1){
                                end = spl;
                            } else {
                                start = spl;
                            }
                            sum ++;
                        }
                        wrapper.between("photograph_time", start, end);
                    } else if(accept.getCondition().equals("1")) {
                        wrapper.notBetween("photograph_time",accept.getValue()+" 00:00:00",accept.getValue()+" 23:59:59").or().isNull("photograph_time");
                    } else if(accept.getCondition().equals("0")) {
                        wrapper.between("photograph_time",accept.getValue()+" 00:00:00",accept.getValue()+" 23:59:59");
                    }
                }
            }
            List<EquipmentMaintain> equipmentMaintains = maintainMapper.selectList(wrapper);
            for(EquipmentMaintain equip:equipmentMaintains){
                idAll.add(equip.getId());
            }
            if(equipmentMaintains.size()==0){
                idAll.add("没有东西");
            }
            criteria.setIdAll(idAll);
        }
        String order = "work_order desc";
        getPageSize(pageable,order);
        return baseMapper.selectList(QueryHelpPlus.getPredicate(EquipmentMaintain.class,criteria));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void download(List<EquipmentMaintainDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        long sum = 1;
        for (EquipmentMaintainDto equip : all) {
            Map<String, Object> map = new LinkedHashMap<>();
            if(equip.getPhotograph()!=null && !equip.getPhotograph().equals("")){
                String[] split = equip.getPhotograph().split(",");
                equip.setEquipSum(split.length);
            }else {
                equip.setEquipSum(0);
            }
            map.put("序号", sum);
            map.put("维护工单", equip.getWorkOrder());
            map.put("设备名称", equip.getEquipName());
            map.put("维护人员", equip.getMaintainerName());
            map.put("维护等级", equip.getGrade());
            map.put("维护频次", equip.getFrequency());
            String s = equip.getPhotographTime().toString();
            String substring = s.substring(0, s.length() - 2);
            map.put("维护时间",substring);
            map.put("设备拍照", equip.getEquipSum()+"张");
            sum ++;
            list.add(map);
        }
        // 创建操作日志信息
        LogVo logVo = new LogVo();
        String name = "[导出]了" + "[设备维护记录信息]";
        logVo.setBehavior(name);
        logVo.setAction(LogEnumeration.LEADING_OUT.getMessage());
        logsService.save(logVo);
        FileUtil.downloadExcel(list, response);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addEquipment(EquipmentMaintain equipment) {
        EquipmentMaintain workOrder = this.getOne(new LambdaQueryWrapper<EquipmentMaintain>()
                .eq(EquipmentMaintain::getWorkOrder, equipment.getWorkOrder()));
        if(workOrder!=null){
            throw new BadRequestException("维护工单已存在");
        }
        Equipment equipment1 = equipmentMapper.selectById(equipment.getEquipNumber());
        if(equipment1 == null){
            throw new BadRequestException("所选设备不存在");
        }

        if(equipment1.getEquipSonName().equals("") || equipment1.getEquipSonName()==null){
            equipment.setEquipName(equipment1.getEquipName());
        }else {
            equipment.setEquipName(equipment1.getEquipSonName());
        }

        User user = userMapper.selectById(equipment.getMaintainerUserId());
        if(user==null){
            throw new BadRequestException("所选人员不存在");
        }
        equipment.setMaintainerName(user.getNickName());


        // 创建操作日志
        LogVo logVo = new LogVo();
        String name1 = "[添加]了"+ " [" + equipment.getEquipName()+ "] " + "设备维护记录信息";
        logVo.setBehavior(name1);
        logVo.setAction(LogEnumeration.Add_TO.getMessage());
        logsService.save(logVo);

        String replace = UUID.randomUUID().toString().replace("-", "");
        equipment.setId(replace);
        equipment.setCreateUserTime(new Timestamp(System.currentTimeMillis()));
        maintainMapper.insert(equipment);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void editEquipment(EquipmentMaintain equipment) {
        EquipmentMaintain workOrder = this.getOne(new LambdaQueryWrapper<EquipmentMaintain>()
                .eq(EquipmentMaintain::getWorkOrder, equipment.getWorkOrder()));
        if(workOrder!=null){
            if(!workOrder.getId().equals(equipment.getId())){
                throw new BadRequestException("维护工单已存在");
            }
        }
        Equipment equipment1 = equipmentMapper.selectById(equipment.getEquipNumber());
        if(equipment1 == null){
            throw new BadRequestException("所选设备不存在");
        }
        if(equipment1.getEquipSonName().equals("") || equipment1.getEquipSonName()==null){
            equipment.setEquipName(equipment1.getEquipName());
        }else {
            equipment.setEquipName(equipment1.getEquipSonName());
        }


        User user = userMapper.selectById(equipment.getMaintainerUserId());
        if(user==null){
            throw new BadRequestException("所选人员不存在");
        }
        equipment.setMaintainerName(user.getNickName());

        EquipmentMaintain maintain = maintainMapper.selectById(equipment.getId());
        Equipment equipment2 = equipmentMapper.selectById(maintain.getEquipNumber());

        // 修改前
        MaintainVo front = new MaintainVo();
        front.setWorkOrder(maintain.getWorkOrder());
        front.setEquipType(equipment2.getEquipName());
        front.setEquipName(maintain.getEquipName());
        front.setFrequency(maintain.getFrequency());
        front.setGrade(maintain.getGrade());
        front.setMaintain(maintain.getMaintainerName());
        front.setMaintainTime(maintain.getPhotographTime().toString());
        front.setStation(equipment2.getStackNumber());


        // 修改后
        MaintainVo after = new MaintainVo();
        after.setWorkOrder(equipment.getWorkOrder());
        after.setEquipType(equipment1.getEquipName());
        after.setEquipName(equipment.getEquipName());
        after.setFrequency(equipment.getFrequency());
        after.setGrade(equipment.getGrade());
        after.setMaintain(equipment.getMaintainerName());
        after.setMaintainTime(equipment.getPhotographTime().toString());
        after.setStation(equipment1.getStackNumber());

        // 创建操作日志
        String s = ContrastObjUtil.comparObj(after,front);
        LogVo logVo = new LogVo();
        String name = "[修改]了"+ " [" + maintain.getEquipName() + "] " + "设备维护记录信息 ";
        logVo.setBehavior(name);
        logVo.setInformation(s);
        logVo.setAction(LogEnumeration.MODIFY.getMessage());
        logsService.save(logVo);

        maintainMapper.updateById(equipment);
    }
}
